package com.shire.shire_interface.service.commandcenter.queues;

import com.alibaba.fastjson.JSONObject;
import com.shire.shire_interface.common.utils.DateUtil;
import com.shire.shire_interface.constants.Constants;
import com.shire.shire_interface.constants.WxConstants;
import com.shire.shire_interface.controller.kf.KfChatController;
import com.shire.shire_interface.dao.invite.WxInviteSubTaskDao;
import com.shire.shire_interface.dao.invite.WxInviteTaskDao;
import com.shire.shire_interface.model.command.WxCommand;
import com.shire.shire_interface.model.friend.WxFriendLog;
import com.shire.shire_interface.model.invite.*;
import com.shire.shire_interface.model.user.WxAccount;
import com.shire.shire_interface.service.commandcenter.WxCommandService;
import com.shire.shire_interface.service.friend.WxFriendLogService;
import com.shire.shire_interface.service.group.WxGroupMemberService;
import com.shire.shire_interface.service.group.WxGroupService;
import com.shire.shire_interface.service.invite.WxInviteSettingService;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Random;

@Service
public class InviteCommandQueue extends GappedCommandQueue {
    private static Logger logger = LoggerFactory.getLogger(KfChatController.class);
    @Resource
    private WxInviteSubTaskDao inviteSubTaskDao;

    @Resource
    private WxInviteTaskDao inviteTaskDao;

    private WxInviteSetting inviteSetting;

    @Resource
    private WxCommandService commandService;

    @Resource
    private WxGroupService groupService;

    @Resource
    private WxGroupMemberService groupMemberService;

    @Resource
    private WxFriendLogService friendLogService;

    @Resource
    private WxInviteSettingService inviteSettingService;

    private static InviteCommandQueue instance;

    @PostConstruct
    public void init() {
        instance = this;
//        loadAllDevice();
    }

    public static InviteCommandQueue getInstance() {
        return instance;
    }

    public InviteCommandQueue getQueueForAccount(WxAccount account) {
        return new InviteCommandQueue(account,
                WxConstants.CmdPriority.INVITE,
                inviteSubTaskDao,
                inviteTaskDao,
                commandService,
                groupService,
                groupMemberService,
                friendLogService,
                inviteSettingService);
    }

    public InviteCommandQueue() {
        super();
    }

    public InviteCommandQueue(WxAccount wxAccount,
                              WxConstants.CmdPriority priority,
                              WxInviteSubTaskDao subTaskDao,
                              WxInviteTaskDao taskDao,
                              WxCommandService commandService,
                              WxGroupService groupService,
                              WxGroupMemberService groupMemberService,
                              WxFriendLogService friendLogService,
                              WxInviteSettingService inviteSettingService) {
        super(wxAccount, priority);
        this.inviteSubTaskDao = subTaskDao;
        this.inviteTaskDao = taskDao;
        this.commandService = commandService;
        this.groupService = groupService;
        this.groupMemberService = groupMemberService;
        this.friendLogService = friendLogService;
        this.inviteSettingService = inviteSettingService;

    }

    @Override
    public WxCommand getNextCommand() {
        // get current account invite settings
        synchronized (this.wxAccount.getWxid().intern()) {
            if (this.lastReturnTime != null && (new Date()).getTime() < this.lastReturnTime.getTime())
                return null;
            inviteSetting = this.inviteSettingService.getInviteSetting(wxAccount.getCsid(), wxAccount.getWxid());
            if (inviteSetting == null){
                inviteSetting = inviteSettingService.getDefaultSetting();
            }

            if (StringUtils.isNotBlank(inviteSetting.getSleepstart()) && StringUtils.isNotBlank(inviteSetting.getSleepend())) {

                String start  = inviteSetting.getSleepstart();
                if (inviteSetting.getSleepstart().contains(" "))
                    start = inviteSetting.getSleepstart().split(" ")[1];
                Date startDate = DateUtil.String2Date(DateUtil.getDate() + " " + start);
                if (startDate.getTime() < (new Date()).getTime()) { //休息
                    curCmd = null;
                    return super.getNextCommand();
                }

                String end = inviteSetting.getSleepend();
                if (inviteSetting.getSleepend().contains(" "))
                    end = inviteSetting.getSleepend().split(" ")[1];

                Date endDate = DateUtil.String2Date(DateUtil.getDate() + " " + end);
                if (endDate.getTime() > (new Date()).getTime()) { //休息
                    curCmd = null;
                    return super.getNextCommand();
                }
            }

            //检查当日数量上限
            WxInviteDayRecord dayRecordItem = inviteSettingService.getInviteDayRecordForAccount(wxAccount.getCsid(),wxAccount.getId(),DateUtil.Date2String(new Date()));


            if (dayRecordItem == null){
                dayRecordItem = new WxInviteDayRecord();
                dayRecordItem.setCsid(wxAccount.getCsid());
                dayRecordItem.setInvitecount(0);
                dayRecordItem.setSenddate(DateUtil.Date2String(new Date()));
                dayRecordItem.setWxaccountid(wxAccount.getId());
            }

            if (inviteSetting.getDaylimit() != null && dayRecordItem.getInvitecount() >= inviteSetting.getDaylimit()) {
                return null;
            }

            WxInviteTaskExample taskExample = new WxInviteTaskExample();
            taskExample.createCriteria().andWxaccountidEqualTo(wxAccount.getWxid()).andTaskstatusEqualTo(Constants.YesNo.YES.getCode());
            taskExample.setCheckFinished(true);
            List<WxInviteTask> taskList = inviteTaskDao.selectByExample(taskExample);
            for (WxInviteTask task : taskList) {
                if (task.getAddcount() >= task.getItemcount())
                    continue;
                if (task.getStarttime() != null && task.getStarttime().getTime() > (new Date()).getTime())
                    continue;

                //取得第一个需要发送的任务
                if (this.lastReturnTime == null || (new Date()).getTime() - this.lastReturnTime.getTime() > inviteSetting.getIntervalstart() * 1000) {
                    WxInviteSubTaskExample subTaskExample = new WxInviteSubTaskExample();
                    subTaskExample.createCriteria().andWxaccountEqualTo(wxAccount.getWxid()).andRststatusEqualTo(-999).andTaskidEqualTo(task.getId());

                    List<WxInviteSubTask> subTaskList = this.getInviteSubTaskDao().selectByExample(subTaskExample);
                    if (subTaskList.size() < 1)
                        continue;//没有需要发送的好友邀请

                    WxInviteSubTask subTask = subTaskList.get(0);

                    WxCommand cmd = null;
                    if (subTask.getWxgroup() != null && StringUtils.isNotBlank(subTask.getWxgroup())) {
                        cmd = commandService.getAddGroupMemberCmd(wxAccount,
                                subTask.getWxgroup(),
                                subTask.getWxinviteeaccount(),
                                inviteSetting.getValidationmsg(),
                                WxConstants.CmdTaskType.INVITE,
                                subTask.getId());
                    } else {
                        JSONObject jsonObject = new JSONObject();
                        jsonObject.put("wxId", subTask.getWxinviteeaccount());
                        jsonObject.put("message", inviteSetting.getValidationmsg());
                        cmd = commandService.generateCmdObject(wxAccount.getCsid(),
                                wxAccount.getId(),
                                jsonObject.toJSONString(),
                                WxConstants.CmdTaskType.INVITE,
                                subTask.getId(),
                                WxConstants.CmdType.CRK_ADD_WXID,
                                WxConstants.CmdPriority.INVITE);

                        WxFriendLog friendLog = new WxFriendLog();
                        friendLog.setAddtype(WxConstants.FriendAddType.FROMSEARCH.getCode());
                        friendLog.setWxaccount(wxAccount.getWxid());
                        friendLog.setRststatus(cmd.getRststatus());
                        friendLog.setApplymsg(inviteSetting.getValidationmsg());
                        friendLog.setCmdid(cmd.getId());
                        friendLog.setCmdtype(WxConstants.CmdType.CRK_ADD_WXID.getCode());
                        friendLog.setCreatetime(new Date());
                        friendLog.setCsid(wxAccount.getCsid());
                        friendLog.setKeyword(subTask.getWxinviteeaccount());
                        friendLog.setTasktype(WxConstants.CmdTaskType.INVITE.getCode());
                        friendLog.setTaskid(subTask.getId());
                        friendLog.setAddresult(0);
                        friendLogService.inserFriendLog(friendLog);
                    }

                    if (cmd == null) {
                        subTask.setRststatus(20008);
                        subTask.setAddstatus(3);
                        subTask.setUpdatetime(new Date());
                        inviteSubTaskDao.updateByPrimaryKeySelective(subTask);
                        //更新task
                        if (task.getSenditemcount() != null)
                            task.setSenditemcount(task.getSenditemcount() + 1);
                        else
                            task.setSenditemcount(1);
                        inviteTaskDao.updateByPrimaryKey(task);
                        continue;
                    }

                    //更新subtask
                    subTask.setCmdid(cmd.getId().intValue());
                    subTask.setRststatus(WxConstants.CmdStatus.SENT.getCode());
                    subTask.setUpdatetime(new Date());
                    subTask.setAddstatus(1);
                    inviteSubTaskDao.updateByPrimaryKey(subTask);

                    //更新task
                    if (task.getSenditemcount() != null)
                        task.setSenditemcount(task.getSenditemcount() + 1);
                    else
                        task.setSenditemcount(1);
                    inviteTaskDao.updateByPrimaryKey(task);

                    dayRecordItem.setInvitecount(dayRecordItem.getInvitecount() + 1);

                    if (dayRecordItem.getId() == null) {
                        inviteSettingService.insertInviteDayRecord(dayRecordItem);
                    } else {
                        inviteSettingService.updateInviteDayRecord(dayRecordItem);
                    }

                    //更新最近一次发送时间
                    int interval = inviteSetting.getIntervalend() - inviteSetting.getIntervalstart();


                    Random random = new Random((new Date()).getTime());
                    interval = inviteSetting.getIntervalstart() + random.nextInt(interval);
                    this.lastReturnTime = new Date((new Date()).getTime() + interval * 1000);

                    return cmd;
                }
            }
        }
        return null;
    }


    public WxInviteSubTaskDao getInviteSubTaskDao() {
        return inviteSubTaskDao;
    }

    public void setInviteSubTaskDao(WxInviteSubTaskDao inviteSubTaskDao) {
        this.inviteSubTaskDao = inviteSubTaskDao;
    }
}
